/*
 * Copyright 2009 Armando Blancas
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package taskgraph.tasks.text;

import java.io.IOException;
import java.io.InterruptedIOException;

import taskgraph.ports.CharInputPort;
import taskgraph.ports.CharOutputPort;
import taskgraph.tasks.PrimitiveTask;


/**
 * Concatenates two lines of text.
 * 
 * <p>Puts together the contents of the first and second line.
 *  
 * @author Armando Blancas
 * @see taskgraph.ports.CharInputPort
 * @see taskgraph.ports.CharOutputPort
 */
public class ConcatLines extends PrimitiveTask {

	private CharInputPort first;
	private CharInputPort second;
	private CharOutputPort output;

	/**
	 * This constructor allows creating instances as beans.
	 */
    public ConcatLines() {
    	// do nothing
    }

	/**
     * Creates a fully configured instance.
     * 
     * @param first The char first input port.
     * @param second The char second input port
     * @param output The char output port.
     */
    public ConcatLines(final CharInputPort first, 
    		           final CharInputPort second,
    		           final CharOutputPort output) {
    	setFirstInput(first);
    	setSecondInput(second);
    	setOutput(output);
    }

    /**
     * Gets the first input port.
     * 
	 * @return The char input port.
	 */
	public CharInputPort getFirstInput() {
		return first;
	}

    /**
     * Gets the output port.
     * 
	 * @return The char output port.
	 */
	public CharOutputPort getOutput() {
		return output;
	}

    /**
     * Gets the second input port.
     * 
	 * @return The char second input port.
	 */
	public CharInputPort getSecondInput() {
		return second;
	}
	
	/**
     * Concatenates the lines from the input ports
     * and writes the resulting line to the output port.
     * The process stops when either input port ends.
	 */
	@Override
    public void run() {
    	try {
    		while (!Thread.currentThread().isInterrupted()) {
    			String firstLine = first.readLine();
    			String secondLine = second.readLine();
    			
    			if (firstLine == null || secondLine == null) {
    				break;
    			}
            	output.println(firstLine + secondLine);
            }
        } catch (InterruptedIOException ie) {
        	// interruption request
        } catch (IOException ioe) {
        	// pipe synch error
            log.error("ConcatLines#run()", ioe);
        } finally {
			first.close();
			output.close();
        }
    }

	/**
	 * Sets the first input port.
	 * 
	 * @param first The char input port.
	 */
    public void setFirstInput(final CharInputPort first) {
    	if (first == null)
    		throw new IllegalArgumentException("first == null");
 		this.first = first;
	}

	/**
	 * Sets the output port.
	 * 
	 * @param output The char output port.
	 */
    public void setOutput(final CharOutputPort output) {
    	if (output == null)
    		throw new IllegalArgumentException("output == null");
 		this.output = output;
	}

	/**
	 * Sets the second input port.
	 * 
	 * @param second The char input port.
	 */
    public void setSecondInput(final CharInputPort second) {
    	if (second == null)
    		throw new IllegalArgumentException("second == null");
 		this.second = second;
	}

}
